package com.web709.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.web709.common.R;
import com.web709.entity.ExchangeGoods;
import com.web709.entity.PointsAccounts;
import com.web709.entity.PointsTransactions;
import com.web709.service.ExchangeGoodsService;
import com.web709.service.PointsAccountsService;
import com.web709.service.PointsTransactionsService;
import com.web709.util.JwtUtils;
import io.jsonwebtoken.Claims;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

@RestController
@RequestMapping("/points")
@Api(tags = "积分管理接口")
@Slf4j
public class PointsController {
    @Autowired
    private PointsAccountsService pointsAccountsService;

    @Autowired
    private PointsTransactionsService pointsTransactionsService;

    @Autowired
    private ExchangeGoodsService exchangeGoodsService;

    @GetMapping("/getVolunteerPoints/{id}")
    @ApiOperation(value = "根据志愿者ID查询积分信息")
    @ApiImplicitParam(name = "id", value = "志愿者ID", required = true, paramType = "path", dataType = "Integer")
    public R<PointsAccounts> getVolunteerPoints(@PathVariable Integer id) {
        QueryWrapper<PointsAccounts> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("volunteer_id", id);
        PointsAccounts pointsAccounts = pointsAccountsService.getOne(queryWrapper);

        if (pointsAccounts == null) {
            pointsAccounts = new PointsAccounts();
            pointsAccounts.setUserId(id);
            pointsAccounts.setTotalPoints(0);
            pointsAccounts.setRedeemedPoints(0);
            pointsAccounts.setRemainingPoints(0);
            pointsAccountsService.save(pointsAccounts);
        }

        return R.success(pointsAccounts);
    }

    //查询积分总数、已兑换积分、剩余积分
    @GetMapping("/getPoints")
    @ApiOperation(value = "查询志愿者积分总数、已兑换积分、剩余积分")
    @ApiImplicitParam(name = "token", required = false, paramType = "header", dataType = "String")
    public R<PointsAccounts> getPoints(HttpServletRequest request) {
        String token = request.getHeader("token");
        Claims claims = JwtUtils.parseJWT(token);
        Integer userId = (Integer) claims.get("userId");
        QueryWrapper<PointsAccounts> pointsAccountsQueryWrapper = new QueryWrapper<>();
        pointsAccountsQueryWrapper.eq("volunteer_id", userId);
        PointsAccounts pointsAccounts = pointsAccountsService.getOne(pointsAccountsQueryWrapper);

        if (pointsAccounts == null) {
            PointsAccounts pointsAccounts1 = new PointsAccounts();
            pointsAccounts1.setUserId(userId);
            pointsAccounts1.setTotalPoints(0);
            pointsAccounts1.setRedeemedPoints(0);
            pointsAccounts1.setRemainingPoints(0);
            pointsAccountsService.save(pointsAccounts1);
            pointsAccounts = pointsAccounts1;
        }
        
        // 计算剩余积分 = 总积分 - 已兑换积分
        pointsAccounts.setRemainingPoints(pointsAccounts.getTotalPoints() - pointsAccounts.getRedeemedPoints());
        // 更新积分账户
        pointsAccountsService.updateById(pointsAccounts);
        
        return R.success(pointsAccounts);
    }

    //积分详情记录
    @GetMapping("/getPointsTransactions")
    @ApiOperation(value = "积分详情记录")
    @ApiImplicitParam(name = "token", required = false, paramType = "header", dataType = "String")
    public R<List<PointsTransactions>> getPointsTransactions(HttpServletRequest request) {
        String token = request.getHeader("token");
        Claims claims = JwtUtils.parseJWT(token);
        Integer userId = (Integer) claims.get("userId");
        // 传入用户id，查询用户的积分详情记录
        List<PointsTransactions> pointsTransactions = pointsTransactionsService.getByUserId(userId);
        if (pointsTransactions == null) {
            return R.error("用户积分详情记录不存在");
        }
        return R.success(pointsTransactions);
    }

    // 积分兑换商品
    @PostMapping("/exchangeProduct")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", required = false, paramType = "header", dataType = "String"),
            @ApiImplicitParam(name = "price", required = true, paramType = "query", dataType = "Integer")
    })
    @ResponseBody
    @ApiOperation(value = "积分兑换商品", notes = "用户兑换商品,这里有一个bug，兑换商品的时候是按照积分数兑换的，不是商品id，添加商品的时候不要有重复的积分数的商品")
    public R<String> exchangeProduct(HttpServletRequest request,@RequestParam Integer productId,
                                     @RequestParam Integer price) {
        // 获取并解析token
        String token = request.getHeader("token");
        if (token == null || token.isEmpty()) {
            return R.error("未提供token");
        }
        Claims claims;
        try {
            claims = JwtUtils.parseJWT(token);
        } catch (Exception e) {
            log.error("Token解析失败", e);
            return R.error("无效的token");
        }
        Integer userId = (Integer) claims.get("userId");
        if (userId == null) {
            return R.error("用户ID不存在");
        }

        // 获取用户积分账户

        QueryWrapper<PointsAccounts> pointsAccountsQueryWrapper = new QueryWrapper<>();
        QueryWrapper<PointsAccounts> v = pointsAccountsQueryWrapper.eq("volunteer_id", userId);
        PointsAccounts pointsAccounts = pointsAccountsService.getOne(v);
        if (pointsAccounts == null) {
            PointsAccounts pointsAccounts1 = new PointsAccounts();
            pointsAccounts1.setUserId(userId);
            pointsAccounts1.setTotalPoints(0);
            pointsAccounts1.setRedeemedPoints(0);
            pointsAccounts1.setRemainingPoints(0);
            pointsAccountsService.save(pointsAccounts1);
            pointsAccounts = pointsAccounts1;
        }
        // 判断用户积分是否足够
        if (pointsAccounts.getRemainingPoints() < price) {
            return R.error("用户积分不足");
        }
        // totalPoints保持不变，只增加redeemedPoints
        pointsAccounts.setRedeemedPoints(pointsAccounts.getRedeemedPoints() + price);
        pointsAccounts.setRemainingPoints(pointsAccounts.getTotalPoints() - pointsAccounts.getRedeemedPoints());
        pointsAccountsService.updateById(pointsAccounts);
        // 写入积分记录
        pointsTransactionsService.exchangeProduct(userId, price,productId);

        //写入exchange表
        ExchangeGoods exchangeGoods = new ExchangeGoods();
        exchangeGoods.setUserId(userId);
        exchangeGoods.setProductId(productId);
        exchangeGoods.setStatus('1');
        exchangeGoodsService.save(exchangeGoods);

        return R.success("兑换成功");
    }


    @GetMapping("/getPointsTransactionAll")
    @ApiOperation(value = "积分详情记录")
    @ApiImplicitParam(name = "token", required = false, paramType = "header", dataType = "String")
    public R<List<PointsTransactions>> getPointsTransactions() {
        // 传入用户id，查询用户的积分详情记录
        List<PointsTransactions> pointsTransactions = pointsTransactionsService.list();
        if (pointsTransactions == null) {
            return R.error("用户积分详情记录不存在");
        }
        return R.success(pointsTransactions);
    }

}
